Completed
Push — develop ( 48b424...bab30d )
by Daniel
15:53 queued 09:41
created

manager.js ➔ copyBlocks   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 8.8571
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
;(function($, window, document, undefined) {
2
	'use strict';
3
4
	var editorVal = '';
5
	var inactiveBlockClass = 'sm-inactive';
6
	var editing = false;
7
	var updated = false;
8
	var dialogEditOpened = false;
9
	var blockPositions = {};
10
	var emptyPositionsObj = {};
11
	var template = {};
12
	var origin = {};
13
	var inlineForm = {};
14
	var dialogConfirm = {};
15
	var dialogEdit = {};
16
	var dialogCopy = {};
17
	var cButtons = {};
18
	var dButtons = {};
19
	var eButtons = {};
20
	var lButtons = {};
21
	var blockObj = {};
22
	var blockData = {
23
		editable: ' editable',
24
		block: {}
25
	};
26
	var msgObj = {};
27
	var saveBtn = {};
28
29
	// These variables are defined in template file
30
	var lang = {};
31
	var config = {};
32
	var editMode = false;
33
34
	// These objects are provided by third-party scripts
35
	var phpbb = {};
36
	var tinymce = {};
37
	var twig = {};
38
39
	var fixPaths = function(subject) {
40
		return subject.replace(new RegExp('(?:href|src)=(?:"|\')((?:.\/)?(?:\.\.\/)+)(?:.*?)(?:"|\')', 'gmi'), function(match, g1) {
41
			return match.replace(g1, config.webRootPath);
42
		});
43
	};
44
45
	var removeGrid = function(items) {
46
		items.removeClass(function() {
47
			var matches = this.className.match(/grid__col+(\S+)?/gi);
48
			return (matches) ? matches.join(' ') : '';
49
		});
50
	};
51
52
	var sortHorizontal = function(items) {
53
		var numItems = items.length;
54
		var numCols = (items.parent().data('columns') !== undefined) ? ((items.parent().data('columns') <= 5) ? items.parent().data('columns') : 5) : 3;
55
		var itemsLeft = numItems % numCols;
56
		var divisibleItems = numItems - itemsLeft;
57
58
		if (numItems <= numCols) {
59
			numCols = numItems;
60
		} else if (items.parent().hasClass('equal')) {
61
			if (itemsLeft > 0 && numCols > 3) {
62
				for (var i = 1; i < itemsLeft; i++) {
63
					if (numItems % (numCols - i) === 0) {
64
						numCols = numCols - i;
65
						break;
66
					}
67
				}
68
			}
69
			divisibleItems = numItems;
70
			itemsLeft = 0;
71
		}
72
73
		removeGrid(items);
74
75
		if (divisibleItems > 0) {
76
			items.slice(0, divisibleItems).addClass('grid__col grid__col--1-of-' + numCols);
77
		}
78
79
		if (itemsLeft) {
80
			var n = 1;
81
			if (itemsLeft < 2) {
82
				n = 5;
83
				itemsLeft = 5;
84
			}
85
			items.slice(divisibleItems, numItems)
86
				.addClass('grid__col grid__col--' + n + '-of-' + itemsLeft);
87
		}
88
	};
89
90
	var showAllPositions = function() {
91
		blockPositions.addClass('show-position');
92
		emptyPositionsObj.removeClass('empty-position').siblings('.grid__col').removeClass('lastUnit');
93
	};
94
95
	var hideEmptyPositions = function() {
96
		blockPositions.removeClass('show-position');
97
		emptyPositionsObj = $('.block-position:not(:has(".block"))').addClass('empty-position').each(function() {
98
			$(this).siblings('.grid__col').last().addClass('lastUnit');
99
		});
100
	};
101
102
	var makeEditable = function(element) {
103
		if (editing === true) {
104
			inlineForm.children(':input').trigger('blur');
105
			return;
106
		}
107
		editing = true;
108
		editorVal = element.removeClass('editable').text();
109
		inlineForm.show().appendTo(element.text('')).children(':input').val(editorVal).focus().select().end();
110
	};
111
112
	var undoEditable = function(v) {
113
		var element = inlineForm.parent();
114
115
		editing = false;
116
		editorVal = '';
117
		element.addClass('editable').text(v);
118
		inlineForm.hide().appendTo($('body'));
119
	};
120
121
	var renderBlock = function(blockObj, blockData) {
122
		var id = 'block-editor-' + blockData.block.id;
123
124
		// if tinymce editor instance already exists, remove it
125
		if (tinymce.get(id)) {
126
			tinymce.EditorManager.execCommand('mceFocus', false, id);                    
127
			tinymce.EditorManager.execCommand('mceRemoveEditor', true, id);
128
		}
129
130
		blockData.block.content = fixPaths(blockData.block.content);
131
		blockObj.html(template.render(blockData));
132
133
		// if custom block, add editor
134
		if (blockData.block.name === "blitze.sitemaker.block.custom") {
135
			if (blockObj.find('#' + id).length) {
136
				tinymce.EditorManager.execCommand('mceAddEditor', false, id);
137
			} else if (blockData.data.content.indexOf('script') > -1) {
138
				eval(blockObj.find('.sm-block-content').html());
0 ignored issues
show
Security Performance introduced by
Calls to eval are slow and potentially dangerous, especially on untrusted code. Please consider whether there is another way to achieve your goal.
Loading history...
139
			}
140
		}
141
	};
142
143
	var saveLayout = function() {
144
		var blocks = {};
145
		$('.block-position').each(function() {
146
			var weight = 0;
147
			var pos = $(this).attr('id');
148
			$(this).find('.block').each(function() {
149
				var id = $(this).attr('id');
150
				if (pos !== undefined && id !== undefined) {
151
					var bid = id.substring(6);
152
					blocks[bid] = {
153
						'position': pos.substring(4),
154
						'weight': weight
155
					};
156
					weight++;
157
				}
158
			});
159
		});
160
161
		$.post(config.ajaxUrl + '/blocks/save_blocks', {route: config.route, blocks: blocks}, function() {
162
			saveBtn.button('disable');
163
			updated = false;
164
		});
165
	};
166
167
	var addBlock = function(posID, blockName, droppedElement) {
168
		$(droppedElement).removeAttr('role aria-disabled data-block class style')
169
			.addClass('block')
170
			.html('<div class="ui-state-highlight sm-block-spacing sortable" style="padding: 5px"><i class="fa fa-spinner fa-2x fa-spin"></i> ' + lang.ajaxLoading + '</div>');
171
172
		var data = {
173
			block: $.trim(blockName),
174
			weight: droppedElement.parent().find('.block').index(droppedElement),
175
			route: config.route,
176
			ext: config.ext,
177
			position: posID
178
		};
179
180
		$.getJSON(config.ajaxUrl + '/blocks/add_block', data, function(result) {
181
			updated = false;
182
			if (result.id === '') {
183
				$(droppedElement).remove();
184
				return;
185
			}
186
187
			var blockObj = $(droppedElement).attr('id', 'block-' + result.id);
188
189
			renderBlock(blockObj, { block: result });
190
			blockObj.children().not('.block-controls')
191
				.show('scale', {percent: 100}, 1000);
192
193
			if (updated) {
194
				saveLayout();
195
			}
196
		});
197
	};
198
199
	var getEditForm = function(block) {
200
		$.getJSON(config.ajaxUrl + '/blocks/edit_block', {id: block.attr('id').substring(6)}, function(resp) {
201
			blockData.block = resp;
202
			if (resp.form) {
203
				dialogEdit.html(resp.form);
204
				dialogEdit.find('#block-settings').tabs();
205
				dialogEdit.find('select[data-togglable-settings]').each(function() {
206
					var $this = $(this);
207
208
					$this.change(function() {
209
						phpbb.toggleSelectSettings($this);
210
					});
211
					phpbb.toggleSelectSettings($this);
212
				});
213
				dialogEdit.dialog({buttons: eButtons}).dialog('option', 'title', lang.edit + ' - ' + resp.title).dialog('open');
214
			}
215
		});
216
	};
217
218
	var getCustomClasses = function() {
219
		return dialogEdit.find('#block_class').text().trim();
220
	};
221
222
	var saveForm = function(block) {
223
		var form = $('#edit_form');
224
		var updateSimilar = dialogEdit.dialog('widget').find('#update-similar:checked').length;
225
		var data = {
226
			'id': block.attr('id').substring(6),
227
			'route': config.route,
228
			'similar': updateSimilar,
229
			'class': getCustomClasses()
230
		};
231
232
		form.serializeArray().map(function(prop) {
233
			data[prop.name] = prop.value;
234
		});
235
236
		if (data['config[source]']) {
237
			data['config[source]'] = encodeURI(data['config[source]']);
238
		}
239
240
		dialogEdit.dialog('close');
241
242
		$.post(config.ajaxUrl + '/blocks/save_block', data, function(resp) {
243
			if (resp.list) {
244
				$.each(resp.list, function(i, row) {
245
					renderBlock($('#block-' + row.id), { block: row });
246
				});
247
			}
248
		});
249
	};
250
251
	var updateBlock = function(data) {
252
		if (data.id === undefined) {
253
			return false;
254
		}
255
		$.post(config.ajaxUrl + '/blocks/update_block' + '?route=' + config.route, data, function(resp) {
256
			if (editing === true) {
257
				undoEditable(resp.title);
258
			}
259
		}, 'json');
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
260
	};
261
262
	var customBlockAction = function(data) {
263
		if (data.id === undefined) {
264
			return;
265
		}
266
267
		$.post(config.ajaxUrl + '/blocks/handle_custom_action', data, function(resp) {
268
			if (resp.id) {
269
				var id = 'block-editor-' + resp.id;
270
				var rawHTML = fixPaths(resp.content);
271
				var block = $('#block-' + resp.id + ' > .sm-block-container');
272
				var editor = $('#' + id).attr('data-raw', rawHTML);
273
274
				tinymce.get(id).setContent(rawHTML ? rawHTML : lang.placeholder);
275
276
				if (!resp.content || !editor.data('active')) {
277
					block.addClass(inactiveBlockClass);
278
				} else  {
279
					block.removeClass(inactiveBlockClass);
280
				}
281
			}
282
		});
283
	};
284
285
	var setDefaultLayout = function(set) {
286
		$.post(config.ajaxUrl + '/blocks/set_default_route' + '?route=' + ((set === true) ? config.route : ''));
287
	};
288
289
	var setStartPage = function(info) {
290
		$.post(config.ajaxUrl + '/blocks/set_startpage', $.param(info));
291
	};
292
293
	var setRoutePrefs = function(form) {
294
		$.post(config.ajaxUrl + '/blocks/set_route_prefs' + '?route=' + config.route + '&ext=' + config.ext, form.serialize());
295
	};
296
297
	var copyBlocks = function(copyFrom) {
298
		var position = $('.block-position');
299
		$.getJSON(config.ajaxUrl + '/blocks/copy_route?route=' + config.route + '&ext=' + config.ext + '&' + $.param(copyFrom), function(resp) {
300
			if (resp.list.length === 0) {
301
				return;
302
			}
303
304
			showAllPositions();
305
			position.empty();
306
307
			$.each(resp.list, function(position, blocks) {
308
				var pos = $('#pos-' + position);
309
				$.each(blocks, function(i, row) {
310
					blockData.block = row;
311
					pos.append('<div id="block-' + row.id + '" class="unit size1of1 block"></div>');
312
					renderBlock(pos.find('#block-' + row.id), blockData);
313
				});
314
315
				if (pos.hasClass('horizontal')) {
316
					sortHorizontal(pos.find('.block'));
317
				}
318
			});
319
			hideEmptyPositions();
320
		});
321
	};
322
323
	var processInput = function(e) {
324
		if (editing === false) {
325
			return;
326
		}
327
328
		var id = $(e).parentsUntil('.block').parent().attr('id').substring(6);
329
		var title = $(e).val();
330
331
		if (id && title !== editorVal) {
332
			updateBlock({'id': id, 'field': 'title', 'title': title});
333
		} else {
334
			undoEditable(editorVal);
335
		}
336
		return false;
337
	};
338
339
	var previewBlock = function() {
340
		// make a copy of block data
341
		var data = $.extend(true, {}, blockData);
342
		var formData = dialogEdit.find('#edit_form').serializeArray();
343
		var cssClass = getCustomClasses();
344
345
		$.each(formData, function() {
346
			data.block[this.name] = (typeof data.block[this.name] === 'boolean') ? ((this.value === '1') ? true : false) : this.value;
347
		});
348
349
		data.block['class'] = (cssClass) ? ' ' + cssClass : '';
350
351
		renderBlock(blockObj, data);
352
	};
353
354
	var undoPreviewBlock = function() {
355
		renderBlock(blockObj, blockData);
356
	};
357
358
	var initTinyMce = function() {
359
		tinymce.init({
360
			'selector': 'div.editable-block',
361
			'inline': true,
362
			'image_advtab': true,
363
			'hidden_input': false,
364
			'plugins': [
365
				'advlist autolink lists link image charmap preview hr anchor pagebreak',
366
				'visualblocks visualchars code',
367
				'media nonbreaking save table contextmenu directionality',
368
				'paste textcolor colorpicker textpattern imagetools'
369
			],
370
			'toolbar': [
371
				'undo redo | styleselect | bold italic | forecolor backcolor | alignleft aligncenter alignright alignjustify',
372
				'bullist numlist outdent indent | hr pagebreak | image media | link | table | preview code'
373
			],
374
			'valid_elements': '*[*]',
375
			'end_container_on_empty_block': true,
376
			'setup': function(editor) {
377
				var blockObj = {};
378
				var blockIsInactive = true;
379
				var editorRawHTML = '';
380
				var blockRawHTML = '';
381
382
				editor.on('init', function() {
383
					if (editor.getContent().length === 0) {
384
						editor.setContent(lang.placeholder);
385
					}
386
				});
387
388
				editor.on('focus', function() {
389
					var blockId = editor.id.substring(13);
390
					blockObj = $('#block-' + blockId + ' > .sm-block-container');
391
					blockIsInactive = blockObj.hasClass(inactiveBlockClass);
392
					blockRawHTML = $('#' + editor.id).data('raw');
393
					editorRawHTML = editor.getContent({format: 'raw'});
0 ignored issues
show
Unused Code introduced by
The variable editorRawHTML seems to be never used. Consider removing it.
Loading history...
394
					editor.setContent(blockRawHTML);
395
				});
396
397
				editor.on('keyUp', function() {
398
					if (blockIsInactive && editor.getContent().length) {
399
						blockIsInactive = false;
400
						blockObj.removeClass(inactiveBlockClass);
401
					} else if (!blockIsInactive && !editor.getContent().length) {
402
						blockIsInactive = true;
403
						blockObj.addClass(inactiveBlockClass);
404
					}
405
				});
406
407
				editor.on('blur', function() {
408
					var rawEditorContent = editor.getContent({format: 'raw'}).replace('<p><br data-mce-bogus="1"></p>', '');
409
					var editorContent = editor.getContent();
410
411
					if (rawEditorContent !== blockRawHTML && rawEditorContent !== lang.placeholder) {
412
						if (!editorContent.length) {
413
							rawEditorContent = '';
414
							editor.setContent(lang.placeholder);
415
						}
416
417
						var blockData = $('#' + editor.id).data('raw', rawEditorContent).data();
418
						blockData.id = editor.id.substring(13);
419
						blockData.content = rawEditorContent;
420
421
						customBlockAction(blockData);
422
					} else if (!editorContent) {
423
						editor.setContent(lang.placeholder);
424
					}
425
				});
426
			}
427
		});
428
	};
429
430
	var showMessage = function(message) {
431
		if (message) {
432
			msgObj.html(message);
433
			msgObj.fadeIn().delay(3000).fadeOut();
434
		}
435
	};
436
437
	var showCurrentState = function(hidingBlocks, positions) {
438
		if (hidingBlocks) {
439
			showMessage('<span><i class="fa fa-info-circle fa-blue fa-lg"></i> ' + lang.hidingBlocks + '</span>');
440
		} else if (positions.length) {
441
			showMessage('<span><i class="fa fa-info-circle fa-blue fa-lg"></i> ' + lang.hidingPos + ': <strong>' + positions.join(', ') + '</strong></span>');
442
		}
443
	};
444
445
	$(document).ready(function() {
446
		editMode = window.editMode || false;
447
		lang = window.lang || {};
448
		phpbb = window.phpbb || {};
449
		tinymce = window.tinymce || {};
450
		twig = window.twig || {};
451
		config = window.config || {
452
			ajaxUrl: '',
453
			boardUrl: '',
454
			route: '',
455
			ext: '',
456
			style: ''
457
		};
458
459
		var copyFrom = '';
460
		var body = {};
461
		var blocksPanel = {};
462
		var exPositions = {};
463
		var overPosition = {};
464
		var isHidingBlocks = false;
465
466
		var loader = $('#admin-bar').show().find('#admin-control').click(function() {
467
			if (editMode) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if editMode is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
468
				$(this).toggleClass('admin-bar-toggler').prev().toggle();
469
				body.toggleClass('push-down');
470
				return false;
471
			}
472
		}).find('i');
473
474
		if (editMode) {
475
			inlineForm = $('<form class="inline-form"><input type="text" class="inline-edit" value="" /></form>').hide().appendTo($('body'));
476
477
			msgObj = $('#ajax-message');
478
			emptyPositionsObj = $('.block-position:not(:has(".block"))').addClass('empty-position');
479
480
			template = twig({
481
				data: $.trim($('#block-template-container').html())
482
			});
483
484
			$('#add-block-panel').find('.sitemaker-block').draggable({
485
				addClasses: false,
486
				iframeFix: true,
487
				opacity: 0.7,
488
				helper: 'clone',
489
				appendTo: 'body',
490
				revert: 'invalid',
491
				connectToSortable: '.block-position',
492
				start: function(event, ui) {
493
					$(ui.helper).addClass('dragging');
494
					showAllPositions();
495
					blockPositions.sortable('refresh');
496
					blocksPanel.trigger('click');
497
				},
498
				stop: function() {
499
					window.setTimeout(function() {
500
						if (updated === false) {
501
							hideEmptyPositions();
502
						}
503
					}, 600);
504
				}
505
			});
506
507
			exPositions = $('#ex_positions');
508
			blockPositions = $('.block-position').addClass('block-receiver').sortable({
509
				revert: true,
510
				placeholder: 'ui-state-highlight grid__col sm-block-spacing block sortable placeholder',
511
				connectWith: '.block-position',
512
				cancel: '.editable-block, .inline-edit',
513
				items: '.block',
514
				tolerance: 'pointer',
515
				cursor: 'move',
516
				cursorAt: {
517
					top: -10,
518
					left: -10
519
				},
520
				start: function(event, ui) {
521
					origin = $(ui.item).addClass('dragging').parent('.horizontal');
522
					showAllPositions();
523
					blockPositions.sortable('refresh');
524
				},
525
				over: function(event, ui) {
526
					overPosition = ui.placeholder.parent('.horizontal').children('.block').addClass('sortable');
527
				},
528
				out: function() {
529
					if ($.isEmptyObject(overPosition) === false) {
530
						overPosition.removeClass('sortable');
531
					}
532
				},
533
				update: function(event, ui) {
534
					updated = true;
535
					if ($(ui.item).attr('id') === undefined) {
536
						var posID = $(this).attr('id').substring(4);
537
						var blockName = $(ui.item).attr('data-block');
538
						var replace = $(this).find('div[data-block="' + blockName + '"]');
539
						addBlock(posID, blockName, replace);
540
					} else {
541
						saveBtn.button('enable');
542
					}
543
544
					var items = $(ui.item).removeAttr('style').parent('.horizontal').children('.block');
545
					var item = $(ui.item);
546
547
					item.parent().removeClass('empty-position');
548
					removeGrid(item);
549
550
					if (items.length > 0) {
551
						sortHorizontal(items);
552
					}
553
554
					if (origin.attr('id') !== $(ui.item).parent('.horizontal').attr('id')) {
555
						sortHorizontal(origin.find('.block').removeClass('sortable'));
556
					}
557
				},
558
				stop: function(event, ui) {
559
					$(ui.item).removeClass('dragging sortable').removeAttr('style');
560
					hideEmptyPositions();
561
					$('body').trigger('layoutChanged');
562
				}
563
			}).on('click', '.block-title', function() {
564
				makeEditable($(this));
565
			}).on('submit', '.inline-form', function(e) {
566
				e.preventDefault();
567
				$(this).find('.inline-edit').trigger('blur');
568
			}).on('focusout', '.inline-edit', function() {
569
				processInput($(this));
570
			}).on('click', '.edit-block', function(e) {
571
				e.preventDefault();
572
				blockObj = $(this).parentsUntil('.block').parent();
573
				getEditForm(blockObj);
574
			}).on('click', '.delete-block', function(e) {
575
				e.preventDefault();
576
				blockObj = $(this).parentsUntil('.block').parent();
577
				dialogConfirm.dialog({buttons: dButtons}).dialog('open');
578
			}).each(function() {
579
				var pos = $(this).attr('id').substring(4);
580
				if (exPositions.find('option[value=' + pos + ']').length === 0) {
581
					exPositions.append('<option value="' + pos + '">' + pos + '</option>');
582
				}
583
			});
584
585
			saveBtn = $('#toggle-edit').button().click(function() {
586
				// exit edit mode
587
			}).parent().next().children('a').button({disabled: true}).click(function(e) {
588
				// save changes
589
				e.preventDefault();
590
				saveLayout();
591
			});
592
593
			$('.has-dropdown').click(function(e) {
594
				e.preventDefault();
595
				$(this).parentsUntil('ul').parent().find('.dropped').not($(this)).removeClass('dropped').next().hide();
596
				blocksPanel = $(this).toggleClass('dropped');
597
				blocksPanel.next().toggle();
598
			}).next().mouseleave(function() {
599
				//$(this).prev().trigger('click');
600
			});
601
602
			$('#admin-options').show(100, function() {
603
				var exPos = $.grep(exPositions.val(), function(str) {
604
					return str.length;
605
				});
606
				showCurrentState(isHidingBlocks, exPos);
607
608
				// Thanks KungFuJosh, for this tip
609
				body = $('body').addClass('push-down');
610
			});
611
612
			// Only show style selector if there are other styles
613
			var styleSelector = $('#style-options');
614
			if (styleSelector.find('option').length > 1) {
615
				styleSelector.show();
616
			}
617
618
			$.ajaxSetup({
619
				// add style id to ajax requests
620
				'beforeSend': function(xhr, settings) {
621
					loader.addClass('fa-spinner fa-green fa-spin fa-lg fa-pulse');
622
					settings.url += ((settings.url.indexOf('?') < 0) ? '?' : '&') + 'style=' + config.style;
623
				},
624
				'complete': function(data) {
625
					loader.delay(2000).removeClass('fa-spinner fa-green fa-spin fa-lg fa-pulse');
626
627
					if (data.responseJSON) {
628
						// Display any returned message
629
						if (data.responseJSON.message) {
630
							showMessage(data.responseJSON.message);
631
						}
632
					}
633
				},
634
				'error': function(event) {
635
					showMessage((event.responseJSON && event.responseJSON.message) ? event.responseJSON.message : lang.ajaxError);
636
				}
637
			});
638
639
			eButtons[lang.edit] = function() {
640
				saveForm(blockObj);
641
			};
642
643
			eButtons[lang.cancel] = function() {
644
				undoPreviewBlock();
645
				$(this).dialog('close');
646
			};
647
648
			dButtons[lang.remove] = function() {
649
				var horizontalPos = blockObj.parent('.horizontal');
650
651
				blockObj.remove();
652
				horizontalPos.find('.ui-effects-placeholder').remove();
653
654
				var items = horizontalPos.find('.block');
655
656
				if (items.length > 0) {
657
					sortHorizontal(items);
658
				}
659
660
				hideEmptyPositions();
661
				saveBtn.button('enable');
662
				$(this).dialog('close');
663
			};
664
665
			dButtons[lang.cancel] = function() {
666
				$(this).dialog('close');
667
			};
668
669
			var defDialog = {
670
				autoOpen: false,
671
				modal: true,
672
				width: 'auto',
673
				show: 'slide',
674
				hide: 'slide'
675
			};
676
677
			dialogConfirm = $('#dialog-confirm').dialog(defDialog);
678
679
			// Delete all blocks
680
			lButtons[lang.deleteAll] = function() {
681
				$(this).dialog('close');
682
				$('.block-position').empty();
683
				hideEmptyPositions();
684
				saveBtn.button('enable');
685
				updated = true;
686
			};
687
688
			lButtons[lang.cancel] = function() {
689
				$(this).dialog('close');
690
			};
691
692
			var dialogDeleteAll = $('#dialog-delete-all').dialog(defDialog);
693
			var deleteAll = $('#delete-blocks').button().click(function(e) {
694
				e.preventDefault();
695
				dialogDeleteAll.dialog({buttons: lButtons}).dialog('open');
696
			});
697
698
			// Initiate dialog for block copy
699
			cButtons[lang.copy] = function() {
700
				$(this).dialog('close');
701
				copyBlocks(copyFrom);
702
				deleteAll.parent().show();
703
			};
704
705
			cButtons[lang.cancel] = function() {
706
				$(this).dialog('close');
707
			};
708
709
			// Events for add block dropdown
710
			dialogCopy = $('#dialog-copy').dialog(defDialog);
711 View Code Duplication
			$('#copy-form').find('.layout-action').button().click(function(e) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
712
				e.preventDefault();
713
				copyFrom = $(this).parent().parent().serializeArray();
714
715
				var fromRoute = copyFrom[0].value;
716
				var fromStyle = copyFrom[1].value;
717
				var layoutAction = $(this).data('action');
718
719
				if (fromRoute === '' || (fromRoute ===  config.route && fromStyle === config.style)) {
720
					return false;
721
				}
722
723
				if (layoutAction === 'copy') {
724
					blocksPanel.trigger('click');
725
					dialogCopy.dialog({buttons: cButtons}).dialog('open');
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
726
				} else {
727
					var url = '';
728
729
					url += ((fromRoute.substring(0, 1) === '/') ? config.ajaxUrl : config.boardUrl + '/') + fromRoute;
730
					url += ((url.indexOf('?') >= 0) ? '&' : '?') + 'style=' + fromStyle + '&edit_mode=1';
731
732
					window.location.href = url;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
733
				}
734
			});
735
736
			// Events for edit block dialog
737
			defDialog.open = function() {
738
				if (dialogEditOpened === false) {
739
					var pane = $(this).dialog('widget').find('.ui-dialog-buttonpane');
740
					dialogEditOpened = true;
741
					$('<label class="dialog-check-button"><input id="update-similar" type="checkbox" />' + lang.updateSimilar + '</label>').prependTo(pane);
742
				}
743
			};
744
745
			dialogEdit = $('#dialog-edit').dialog(defDialog).on('click', '.block-class-actions', function(e) {
746
				e.preventDefault();
747
				var action = $(this).data('action');
748
				var editor = dialogEdit.find('#block_class');
749
				switch (action) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
750
					case 'clear':
751
						editor.text('').change();
752
						break;
753
					case 'toggle':
754
						dialogEdit.find('#css-class-options').slideToggle();
755
						break;
756
					case 'undo':
757
					case 'redo':
758
						editor.focus();
759
						document.execCommand(action, false, null);
760
						editor.change();
761
						break;
762
				}
763
			}).on('click', '.class-cat', function(e) {
764
				var id = $(this).attr('href');
765
				var obj = $('#classes-scroller');
766
				obj.animate({
767
					scrollTop: obj.scrollTop() + $(id).position().top
768
				}, 1000);
769
				e.preventDefault();
770
			}).on('click', '.transform', function(e) {
771
				var editor = dialogEdit.find('#block_class');
772
				editor.focus();
773
				document.execCommand('insertText', false, $(this).text() + ' ');
774
				editor.change();
775
				e.preventDefault();
776
			}).on('change', '.block-preview', function() {
777
				previewBlock();
778
			});
779
780
			// Set default layout
781
			$('.default-layout').button().click(function(e) {
782
				var setDefault = $(this).data('set');
783
				setDefaultLayout(setDefault);
784
				e.preventDefault();
785
				if (setDefault === true) {
786
					// set as default
787
					$(this).parent().hide().next().hide().next().show();
788
					deleteAll.parent().hide();
789
				} else {
790
					// remove as default
791
					$(this).parent().hide().prev().hide().prev().show();
792
					deleteAll.parent().show();
793
				}
794
			});
795
796
			// Set start page
797
			$('.sm-startpage').button().click(function(e) {
798
				e.preventDefault();
799
				var info = {};
800
				if ($(this).attr('id') === 'set-startpage') {
801
					// set as startpage
802
					$(this).parent().hide().next().show();
803
					info = {
804
						controller: $(this).data('controller'),
805
						method: $(this).data('method'),
806
						params: $(this).data('params')
807
					};
808
					setStartPage(info);
809
				} else {
810
					// remove as startpage
811
					$(this).parent().hide().prev().show();
812
					setStartPage(info);
813
				}
814
			});
815
816
			isHidingBlocks = $('#route-settings').submit(function(e) {
817
				setRoutePrefs($(this));
818
				e.preventDefault();
819
			}).find('#hide_blocks').is(':checked');
820
821
			window.onbeforeunload = function(e) {
822
				if (updated === true) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if updated === true is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
823
					e = e || window.event;
824
					// For IE and Firefox
825
					if (e) {
826
						e.returnValue = lang.leaveConfirm;
827
					}
828
					// For Safari
829
					return lang.leaveConfirm;
830
				}
831
			};
832
833
			// Init Icon Picker
834
			$('.sitemaker').iconPicker({
835
				selector: '.block-icon',
836
				onSelect: function(item, iconClass) {
837
					var id = item.parentsUntil('.block').parent().attr('id').substring(6);
838
					updateBlock({'id': id, 'icon': iconClass});
839
				}
840
			});
841
842
			initTinyMce();
843
		}
844
	});
845
})(jQuery, window, document);